#!/usr/bin/env python
# -*- coding: utf-8 -*-
#from __future__ import with_statement
__author__="pio"

import cgi, re, os, posixpath, mimetypes
import sys
import datetime
import logging
import urllib2
from cgi import parse_qs, escape
import threading
env = os.environ
host="localhost"
port=12346
today=datetime.date.today().strftime("%Y%m%d")
logFilename= os.path.join(env['PYMUQUE_HOME'],"log","wrapperserver_%s.log"%(today))
logging.basicConfig(level=logging.DEBUG,
              format='%(asctime)s - %(thread)d - %(threadName)s - %(process)d - %(levelname)s - %(message)s',
              filename=logFilename,
              filemode='a'
)
logger = logging.getLogger()

STATUS_CODE_TEXT = {
    100: 'CONTINUE',
    101: 'SWITCHING PROTOCOLS',
    200: 'OK',
    201: 'CREATED',
    202: 'ACCEPTED',
    203: 'NON-AUTHORITATIVE INFORMATION',
    204: 'NO CONTENT',
    205: 'RESET CONTENT',
    206: 'PARTIAL CONTENT',
    300: 'MULTIPLE CHOICES',
    301: 'MOVED PERMANENTLY',
    302: 'FOUND',
    303: 'SEE OTHER',
    304: 'NOT MODIFIED',
    305: 'USE PROXY',
    306: 'RESERVED',
    307: 'TEMPORARY REDIRECT',
    400: 'BAD REQUEST',
    401: 'UNAUTHORIZED',
    402: 'PAYMENT REQUIRED',
    403: 'FORBIDDEN',
    404: 'NOT FOUND',
    405: 'METHOD NOT ALLOWED',
    406: 'NOT ACCEPTABLE',
    407: 'PROXY AUTHENTICATION REQUIRED',
    408: 'REQUEST TIMEOUT',
    409: 'CONFLICT',
    410: 'GONE',
    411: 'LENGTH REQUIRED',
    412: 'PRECONDITION FAILED',
    413: 'REQUEST ENTITY TOO LARGE',
    414: 'REQUEST-URI TOO LONG',
    415: 'UNSUPPORTED MEDIA TYPE',
    416: 'REQUESTED RANGE NOT SATISFIABLE',
    417: 'EXPECTATION FAILED',
    500: 'INTERNAL SERVER ERROR',
    501: 'NOT IMPLEMENTED',
    502: 'BAD GATEWAY',
    503: 'SERVICE UNAVAILABLE',
    504: 'GATEWAY TIMEOUT',
    505: 'HTTP VERSION NOT SUPPORTED',
    
}
def getfield(f):
    """convert values from cgi.Field objects to plain values."""
    if isinstance(f, list):
        return [getfield(x) for x in f]
    else:
        return urllib2.unquote(f.value)
class WSGIResponse(object):
    def __init__(self):
      self.status_code=200
      self.headers={}
      self.headers['Content-type']= 'text/plain'
      self.contents=[]
    def content(self,c):
      self.contents.append(c)
    def __iter__(self):
     for chunk in self.contents:
         yield chunk
#TODO /home/pio/.local/share/Trash/files/google_app_engine/google_appengine/lib/django/django/core/handlers/wsgi.py
class WSGIDataRequest(object):
    def __init__(self,environ):
      self.req={}
      fieldstorage = cgi.FieldStorage(
            fp = environ['wsgi.input'],
            environ = environ,
            keep_blank_values = True
      )
      self.req= dict([(k, getfield(fieldstorage[k])) for k in fieldstorage])
    def get(self):
      return self.req

class dummyApp(object):
    def __init__(self):
      self.test=[]
    def process(self):
      self.test.append(1)
      self.test.pop()
    def get_response(self,request):
      res=WSGIResponse()
      return res


class dummySite(object):
   def __init__(self,a):
        self.num=0
        self.application=a
        logger.info("Site Startup")
        self.method_mapping={}
        self.method_mapping['select']=self._select
        self.method_mapping['stats']=self._stats
        self.method_mapping['ping']=self._ping
        self.method_mapping['list']=self._list
   def _stats(self,env, start_response):
      start_response('200 OK', [('Content-type', 'text/plain')])
      strout="Print Statistic"
      return [strout]     
   def _list(self,env, start_response):
      start_response('200 OK', [('Content-type', 'text/plain')])
      strout="List method:\n"
      strout+='\n'.join(self.method_mapping.keys())
      return [strout]     
   def _select(self,env, start_response):
      request=None
      response=None
      try:
        #request = WSGIRequest(environ)
        request = WSGIDataRequest(env).get()
        response = self.application.get_response(request)
        try:
            status_text = STATUS_CODE_TEXT[response.status_code]
        except KeyError:
            status_text = 'UNKNOWN STATUS CODE'
      except:
        import traceback
        traceback.print_exc()
        status_text = STATUS_CODE_TEXT[500]
        response.status_code=500
      status = '%s %s' % (response.status_code, status_text)
      response_headers = response.headers.items()
      start_response(status, response_headers)  
      return response
   
   def _ping(self,env, start_response):
      start_response('200 OK', [('Content-type', 'text/plain')])
      strout="Pong"
      import time
      time.sleep(3)
      return [strout]     
#######
#
#######
class WSGIPathInfoDispatcher(object):
    def __init__(self, app):
        apps=app.method_mapping
        try:
            apps = apps.items()
        except AttributeError:
            pass
        apps.sort()
        apps.reverse()
        self.apps = [(p.rstrip('/').lstrip('/'), a) for (p, a) in apps]
        logger.info("%s Done!"%__name__)
        self.lock = threading.Lock()
    def __call__(self, environ, start_response):
        #with self.lock:
        path = environ['PATH_INFO'] or '/'
        if path != '/':
          path=path.rstrip('/').lstrip('/')
        for (p, app) in self.apps:
            if path.startswith(p + '/') or path == p:
                environ = environ.copy()
                environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'] + p
                environ['PATH_INFO'] = path[len(p):]
                return app(environ, start_response)
        m='404 Not Found\n\n'
        m+='Todo sistemare la home %s\n'%__name__
        m+='Per la ricerca: select/?qs=ciao&wt=xsearch '
        
        start_response('404 Not Found', [('Content-Type', 'text/plain'), ('Content-Length', '%d'%len(m))])
        return [m]

if __name__ == '__main__':
    from wsgiutils.wsgiServer import WSGIServer
    httpd = WSGIServer((host, port), {'': WSGIPathInfoDispatcher(dummySite(dummyApp()))}, serveFiles=False)
    print "Server listening on port %d" % port
    httpd.serve_forever()

